﻿namespace LearnDSLinkedList;

public class CircularLinkedList
{
    private Node head;
    private Node tail;
    private int size;

    public CircularLinkedList()
    {
        head = null;
        tail = null;
        size = 0;
    }

    public int Length()
    {
        return size;
    }

    public bool IsEmpty()
    {
        return size == 0;
    }

    public void AddLast(int e)
    {
        Node newest = new Node(e, null);
        if (IsEmpty())
        {
            newest.next = newest;
            head = newest;
        }
        else
        {
            newest.next = tail.next;
            tail.next = newest;
        }

        tail = newest;
        size++;
    }

    public void AddFirst(int e)
    {
        Node newest = new Node(e, null);
        if (IsEmpty())
        {
            newest.next = newest;
            head = newest;
            tail = newest;
        }
        else
        {
            tail.next = newest;
            newest.next = head;
            head = newest;
        }

        size++;
    }

    public void AddAny(int e, int position)
    {
        if (position <= 0 || position >= size)
        {
            Console.WriteLine("Invalid Position");
            return;
        }

        Node newest = new Node(e, null);
        Node p = head;
        int i = 1;
        while (i < position - 1)
        {
            p = p.next;
            i++;
        }

        newest.next = p.next;
        p.next = newest;
        size++;
    }

    public int RemoveFirst()
    {
        if (IsEmpty())
        {
            Console.WriteLine("Circular List is Empty");
            return -1;
        }

        int e = head.element;
        tail.next = head.next;
        head = head.next;
        size--;
        if (IsEmpty())
        {
            head = null;
            tail = null;
        }

        return e;
    }

    public int RemoveLast()
    {
        if (IsEmpty())
        {
            Console.WriteLine("Circular List is Empty");
            return -1;
        }

        Node p = head;
        int i = 1;
        while (i < Length() - 1)
        {
            p = p.next;
            i++;
        }

        tail = p;
        p = p.next;
        tail.next = head;
        int e = p.element;
        size--;
        return e;
    }

    public int RemoveAny(int position)
    {
        if (position <= 0 || position >= size - 1)
        {
            Console.WriteLine("Invalid Position");
            return -1;
        }

        Node p = head;
        int i = 1;
        while (i < position - 1)
        {
            p = p.next;
            i++;
        }

        int e = p.next.element;
        p.next = p.next.next;
        size--;
        return e;
    }


    public void Display()
    {
        Node p = head;
        int i = 0;
        while (i < Length())
        {
            Console.Write(p.element + " ");
            p = p.next;
            i++;
        }

        Console.WriteLine();
    }
}